﻿/**
  @file		
  @brief	
  @author	
  @version	
*/

#include "server.h"


U32 CListenReadThread::run()
{

}

U32 CWriteThread::run()
{

}

IServer* CreateServer( U32 u32MaxClientNum, U16 u16ListenPort )
{
	return new CServer( u32MaxClientNum );
}

void	DestoryServer( IServer* poServer )
{
	if ( poServer != NULL )
	{
		delete poServer;
	}
}

CServer::CServer( U32 u32MaxClientNum, U16 u16ListenPort )
	:m_pConnectionArray(NULL),
	m_u16ListenPort(0),
	m_u32MaxClientsNum(0),
	m_u32CurClientsNum(0),
	m_pListenReadThread(NULL),
	m_pWriteThread(NULL)
{
	m_pConnectionArray = new CConnection[u32MaxClientNum];
	for ( U32 u32Idx = 0; u32Idx < u32MaxClientNum; u32Idx++ )
	{
		m_pConnectionArray[u32Idx].Initialize( 0, 1024 * 10, 1024 * 10 );
	}
	m_u32MaxClientsNum = u32MaxClientNum;
	m_u16ListenPort = u16ListenPort;

	m_pListenReadThread = new CListenReadThread();
	m_pWriteThread = new CWriteThread();
}

CServer::~CServer()
{
	delete m_pListenReadThread;
	delete m_pWriteThread;

	delete[] m_pConnectionArray;
}

S32	CServer::StartService()
{
#ifdef OS_WIN32
#else
	m_s32EPollFD = epoll_create( m_u32MaxClientsNum );
	if ( m_s32EPollFD == -1 )
	{
		return -1;
	}

	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = 0;
	if ( (m_s32ListenSocket = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
	{
		return -3;
	}

	int nOnFlag = 1;
	setsockopt( m_s32ListenSocket, SOL_SOCKET, SO_REUSEADDR, (const void *)&nOnFlag, sizeof(nOnFlag) );

	epoll_socket( m_s32ListenSocket, EPOLL_CTL_ADD );

	if( bind( m_s32ListenSocket, (const sockaddr *)&addr, sizeof(addr) ) ) 
	{
		return -4;
	}

	if( listen( m_s32ListenSocket, m_u32MaxClientsNum ) )	
	{
		return -5;
	}

	m_pListenReadThread->start();

	m_pWriteThread->start();
#endif

	return 0;
}

S32 CServer::StopService()
{
#ifdef OS_WIN32
#else
	if ( m_s32ListenSocket != 0 )
	{
		epoll_socket( m_s32ListenSocket, EPOLL_CTL_DEL );
		::close( m_s32ListenSocket );
		m_s32ListenSocket = 0;
	}

	for( U32 u32Idx = 0; u32Idx < this->max_clients; u32Idx++ ) 
	{
		if (m_pConnectionArray[u32Idx].GetSocket() != INVALID_SOCKET)
		{
			epoll_socket( m_pConnectionArray[u32Idx].GetSocket(), EPOLL_CTL_DEL );
		}
	}
#endif

	return 0;
}

S32	CServer::DisconnectClient( U32 u32ClientIdx )
{
	return 0;
}

S32 CServer::GetPackFromClient( U32 u32ClientIdx, U8*& pu8OutData, U32& u32OutDataSize )
{
	return 0;
}

S32 CServer::SendPackToClient( U32 u32ClientIdx, U8* pu8Data, U32 u32DataSize )
{
	return 0;
}

